package edu.sjb.map;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import edu.sjb.characters.GameCharacter;
import edu.sjb.map.prizes.PowerUp;

public class FileMapLoader extends MapLoader {
	protected EntityCharacter mappings;
	protected Level level;

	public FileMapLoader(File levelFile) {

		mappings = new EntityCharacter();
		level = new ListLevel();
		setupFromFile(levelFile);
	}

	private void setupFromFile(File levelFile) {

		try {
			int line = 0;
			BufferedReader levelFileBuffer;
			if (levelFile == null) {
				InputStream is = new FileInputStream(new File(
				        "./levels/level1.sjl"));
				levelFileBuffer = new BufferedReader(new InputStreamReader(is));
			}
			else {
				levelFileBuffer = new BufferedReader(new FileReader(levelFile));
			}
			String text_line = "";
			while ((text_line = levelFileBuffer.readLine()) != null) {
				this.parseLine(text_line, line);
				line++;
			}
			levelFileBuffer.close();
		}
		catch (FileNotFoundException e) {
		}
		catch (IOException e) {
		}
	}

	private void parseLine(String text_line, int line) {
		GameCharacter p = null;
		GameCharacter pClone = null;
		MapObject o = null;
		MapObject oClone = null;
		PrizeMapBrick oPrizeBlock = null;
		for (int i = 0; i < text_line.length(); i++) {
			Character c = new Character(text_line.charAt(i));
			switch (c) {
				case 'B': {
					o = mappings.getEntity(c);
					oClone = (MapObject) o.clonate();
					oClone.setPosX(line * 32);
					oClone.setPosY(i * 32);
					oClone.setSizeX(32);
					oClone.setSizeY(32);
					oClone.image().setBounds(oClone.posX(), oClone.posY(), 32,
					        32);
					level.addEntity(oClone);
					break;
				}
				case 'I': {
					o = mappings.getEntity(c);
					oPrizeBlock = (PrizeMapBrick) o.clonate();
					oPrizeBlock.setPosX(line * 32);
					oPrizeBlock.setPosY(i * 32);
					oPrizeBlock.setSizeX(32);
					oPrizeBlock.setSizeY(32);
					oPrizeBlock.image().setBounds(oPrizeBlock.posX(),
					        oPrizeBlock.posY(), 32, 32);
					level.addEntity(oPrizeBlock);
					PowerUp blockPwUp = oPrizeBlock.powerUp();
					blockPwUp.image().setBounds(blockPwUp.posX(),
					        blockPwUp.posY(), 32, 32);
					blockPwUp.setPosX(oPrizeBlock.posX());
					blockPwUp.setPosY(oPrizeBlock.posY() - 32);
					blockPwUp.setSizeX(32);
					blockPwUp.setSizeY(32);
					blockPwUp.image().setHidden(true);
					level.addPowerUp(blockPwUp);
					break;
				}
				case 'P': {
					o = mappings.getEntity(c);
					oClone = (MapObject) o.clonate();
					oClone.setPosX(line * 32);
					oClone.setPosY(i * 32 - 5);
					oClone.setSizeX(32);
					oClone.setSizeY(32);
					oClone.image().setBounds(oClone.posX(), oClone.posY(), 32,
					        32);
					level.addEntity(oClone);
					break;
				}
				case 'T': {
					o = mappings.getEntity(c);
					oClone = (MapObject) o.clonate();
					oClone.setPosX(line * 32);
					oClone.setPosY(i * 32 - 32);
					oClone.setSizeX(64);
					oClone.setSizeY(64);
					oClone.image().setBounds(oClone.posX(), oClone.posY(), 64,
					        64);
					level.addEntity(oClone);
					break;
				}
				case 'G': {
					p = mappings.getCharacter(c);
					pClone = (GameCharacter) p.clonate();
					pClone.setPosX(line * 32);
					pClone.setPosY(i * 32);
					pClone.setSizeX(32);
					pClone.setSizeY(32);
					pClone.image().setBounds(pClone.posX(), pClone.posY(), 32,
					        32);
					level.addCharacter(pClone);
					break;

				}
				case 'K': {
					p = mappings.getCharacter(c);
					pClone = (GameCharacter) p.clonate();
					pClone.setPosX(line * 32);
					pClone.setPosY(i * 32);
					pClone.setSizeX(32);
					pClone.setSizeY(32);
					pClone.image().setBounds(pClone.posX(), pClone.posY(), 32,
					        32);
					level.addCharacter(pClone);
					break;
				}
			}
		}
	}

	@Override
	public Level getCreatedLevel() {
		return level;
	}
}
